package com.ys.erp.stage_mall_service.service;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ys.erp.common.enums.EnableEnum;
import com.ys.erp.common.enums.old.TypeOldEnum;
import com.ys.erp.common.util.MoneyUtil;
import com.ys.erp.common.util.YsThread;
import com.ys.erp.entity.data.bean.*;
import com.ys.erp.entity.service.*;
import com.ys.erp.framework.bean.dto.StageEmpDTO;
import com.ys.erp.framework.response.PageDTO;
import com.ys.erp.stage_mall_service.bean.condition.GoodsCondition;
import com.ys.erp.stage_mall_service.bean.dto.SpecsDTO;
import com.ys.erp.stage_mall_service.bean.vo.GoodsSpecsVO;
import com.ys.erp.stage_mall_service.bean.vo.GoodsVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author lwj
 * @date 2025/5/28
 */
@Service
@RequiredArgsConstructor
@Slf4j
@RefreshScope
public class GoodsService {

    private final IGoodsService iGoodsService;

    private final IGoodsSpecsService iGoodsSpecsService;

    private final IMiddleGoodsCategoryService iMiddleGoodsCategoryService;

    private final IEventLogService iEventLogService;

    private final GoodsSubscribeService goodsSubscribeService;

    private final IGoodsBrandService iGoodsBrandService;

    private final IGoodsCategoryService iGoodsCategoryService;


    /**
     * 添加或更新商品
     *
     * @param empDTO                登录员工
     * @param con                   请求体
     */
    public void addOrUpGoods(StageEmpDTO empDTO, GoodsCondition.AddOrUpGoodsCon con) {
        Goods goods = new Goods();
        BeanUtils.copyProperties(con, goods);
        goods.setBrandId(con.getBrandId());
        goods.setGoodsBanner(JSONArray.toJSONString(con.getGoodsBanner()));
        goods.setGoodsType(TypeOldEnum.PHYSICAL_PRODUCT.getType());
        goods.setDeliveryType("[0]");
        goods.setGoodsPrice(MoneyUtil.str2Long(con.getGoodsPrice()));
        goods.setYsMoney(MoneyUtil.str2Long(con.getYsMoney()));
        goods.setYsMoneyDescribe(con.getYsMoneyDescribe());
        goods.setScribePrice(MoneyUtil.str2Long(con.getScribePrice()));
        goods.setCostPrice(MoneyUtil.str2Long(con.getCostPrice()));
        goods.setAttrList(JSONObject.toJSONString(con.getAttrList()));
        goods.setIsUseTag(con.getIsUseTag());
        goods.setGoodsTag(JSONArray.toJSONString(con.getGoodsTag()));
        ArrayList<MiddleGoodsCategory> middleGoodsCategories = new ArrayList<>();
        if (Objects.isNull(con.getShowGradeIdList())) {
            goods.setShowGradeId("[]");
        } else {
            goods.setShowGradeId(JSONArray.toJSONString(con.getShowGradeIdList()));
        }
        if (Objects.isNull(con.getQuotaGradeIdList())) {
            goods.setQuotaGradeId("[]");
        } else {
            goods.setQuotaGradeId(JSONArray.toJSONString(con.getQuotaGradeIdList()));
        }
        if (Objects.isNull(con.getCycleQuotaMap())) {
            goods.setCycleQuotaNum("{}");
        } else {
            goods.setCycleQuotaNum(JSONObject.toJSONString(con.getCycleQuotaMap()));
        }
        if (Objects.isNull(con.getCityNameList())) {
            goods.setCityNameList("[]");
        } else {
            goods.setCityNameList(JSONObject.toJSONString(con.getCityNameList()));
        }
        goods.setPetType(JSONArray.toJSONString(con.getPetType()));
        if (con.getSpecsConList().isEmpty()) {
            ArrayList<GoodsCondition.GoodsAttrCon> attrArr = getGoodsAttrCons(goods);
            goods.setAttrList(JSONObject.toJSONString(attrArr));
            GoodsCondition.GoodsSpecsCon goodsSpecsCon = new GoodsCondition.GoodsSpecsCon();
            goodsSpecsCon.setSpecsPrice(con.getGoodsPrice())
                    .setSpecsCostPrice(con.getCostPrice())
                    .setPic(con.getGoodsBanner().getFirst())
                    .setSpecsWeight(con.getGoodsWeight())
                    .setStock(con.getStockTotal().intValue());
            List<GoodsCondition.SpecsCon> specsDtoList = new ArrayList<>();
            GoodsCondition.SpecsCon specsDTO = new GoodsCondition.SpecsCon();
            specsDTO.setKey("规格");
            specsDTO.setValue(goods.getGoodsName());
            specsDtoList.add(specsDTO);
            goodsSpecsCon.setAttrMap(specsDtoList);
            con.getSpecsConList().add(goodsSpecsCon);
        }
        //查询商品规格及库存
        HashMap<Long, Integer> specsStockMap = new HashMap<>();
        if (ObjectUtils.isNotEmpty(con.getId())) {
            QueryWrapper<GoodsSpecs> specsQw = new QueryWrapper<>();
            specsQw.lambda().select(GoodsSpecs::getId, GoodsSpecs::getStock);
            specsQw.lambda().eq(GoodsSpecs::getGoodsId, con.getId());
            specsQw.lambda().eq(GoodsSpecs::getIsDelete, EnableEnum.NO.getEnable());
            Map<Long, Integer> map = iGoodsSpecsService.list(specsQw).stream()
                    .collect(Collectors.toMap(GoodsSpecs::getId, GoodsSpecs::getStock));
            specsStockMap.putAll(map);
        }
        List<Long> subscribeSpecsIds = new ArrayList<>();
        List<GoodsSpecs> saveOrUp = new ArrayList<>();
        long count = con.getSpecsConList().stream().filter(it -> it.getYsCoinDiscount() <= 99).count();
        if (count > 0) {
            goods.setIsCash(EnableEnum.YES.getEnable());
        } else {
            goods.setIsCash(EnableEnum.NO.getEnable());
        }
        for (GoodsCondition.GoodsSpecsCon it : con.getSpecsConList()) {
            GoodsSpecs goodsSpecs = new GoodsSpecs();
            BeanUtils.copyProperties(it, goodsSpecs);

            goodsSpecs.setGoodsSpecs(JSONObject.toJSONString(it.getAttrMap()));
            if (ObjectUtils.isEmpty(it.getPic())) {
                goodsSpecs.setPic(con.getGoodsBanner().getFirst());
            }
            if (specsStockMap.containsKey(goodsSpecs.getId())) {
                Integer integer = specsStockMap.get(goodsSpecs.getId());
                if (integer == 0 && goodsSpecs.getStock() > 0) {
                    subscribeSpecsIds.add(goodsSpecs.getId());
                }
            }
            goodsSpecs.setSpecsPrice(MoneyUtil.str2Long(it.getSpecsPrice()))
                    .setSendGoodsType(it.getSendGoodsType())
                    .setSpecsCostPrice(MoneyUtil.str2Long(it.getSpecsCostPrice()));
            saveOrUp.add(goodsSpecs);
        }
        long totalStock = saveOrUp.stream().mapToLong(GoodsSpecs::getStock).filter(ObjectUtils::isNotEmpty).sum();
        goods.setStockTotal(totalStock);
        if (ObjectUtils.isEmpty(con.getId())) {
            iGoodsService.save(goods);
            for (Long l : con.getCategoryIdList()) {
                MiddleGoodsCategory middleGoodsCategory = new MiddleGoodsCategory();
                middleGoodsCategory.setCategoryId(l);
                middleGoodsCategory.setGoodsId(goods.getId());
                middleGoodsCategories.add(middleGoodsCategory);
            }
            saveOrUp.forEach(it -> it.setGoodsId(goods.getId()));
            iGoodsSpecsService.saveBatch(saveOrUp);
            //添加商品分类
            iMiddleGoodsCategoryService.saveBatch(middleGoodsCategories);
            iEventLogService.insertEvent(empDTO, "新增商品：" + goods.getGoodsName(), goods.getId(), EnableEnum.NO.getEnable(),JSONObject.toJSONString(con));
            return;
        }
        //更新
        Goods byId = iGoodsService.getById(con.getId());
        if (ObjectUtils.isEmpty(byId)) {
            return;
        }
        goods.setId(byId.getId());
        UpdateWrapper<GoodsSpecs> uw = new UpdateWrapper<>();
        uw.lambda().set(GoodsSpecs::getIsDelete, EnableEnum.YES.getEnable())
                .eq(GoodsSpecs::getGoodsId, byId.getId());
        List<Long> collect = saveOrUp.stream().map(GoodsSpecs::getId).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());
        if (!collect.isEmpty()) {
            uw.lambda().notIn(GoodsSpecs::getId, collect);
        }
        iGoodsSpecsService.update(uw);
        iGoodsService.updateById(goods);
        saveOrUp.forEach(it -> it.setGoodsId(byId.getId()));
        iGoodsSpecsService.saveOrUpdateBatch(saveOrUp);
        //更新商品分类
        QueryWrapper<MiddleGoodsCategory> middleGoodsCategoryQw = new QueryWrapper<>();
        middleGoodsCategoryQw.lambda().eq(MiddleGoodsCategory::getGoodsId, goods.getId());
        iMiddleGoodsCategoryService.remove(middleGoodsCategoryQw);
        for (Long l : con.getCategoryIdList()) {
            MiddleGoodsCategory middleGoodsCategory = new MiddleGoodsCategory();
            middleGoodsCategory.setCategoryId(l);
            middleGoodsCategory.setGoodsId(goods.getId());
            middleGoodsCategories.add(middleGoodsCategory);
        }
        iMiddleGoodsCategoryService.saveBatch(middleGoodsCategories);
        //编辑商品发送通知
        goodsSubscribeService.asyncSendMessage(subscribeSpecsIds);
        iEventLogService.insertEvent(empDTO, "编辑商品：" + goods.getGoodsName(), goods.getId(), EnableEnum.NO.getEnable(),JSONObject.toJSONString(con));
    }

    private static ArrayList<GoodsCondition.GoodsAttrCon> getGoodsAttrCons(Goods goods) {
        ArrayList<GoodsCondition.GoodsAttrCon> attrArr = new ArrayList<>();
        GoodsCondition.GoodsAttrCon goodsAttrCon = new GoodsCondition.GoodsAttrCon();
        goodsAttrCon.setKey("规格");
        ArrayList<GoodsCondition.GoodsAttrValuesCon> values = new ArrayList<>();
        GoodsCondition.GoodsAttrValuesCon goodsAttrValues = new GoodsCondition.GoodsAttrValuesCon();
        goodsAttrValues.setValue(goods.getGoodsName());
        values.add(goodsAttrValues);
        goodsAttrCon.setValues(values);
        attrArr.add(goodsAttrCon);
        return attrArr;
    }

    /**
     * 复制商品
     *
     * @param empDTO                    登录员工
     * @param id                        请求对象
     */
    @Transactional(rollbackFor = Exception.class)
    public void copyGoods(StageEmpDTO empDTO, Long id) {
        CompletableFuture<Goods> goodsFuture = YsThread.execute(() -> {
            return iGoodsService.getById(id);
        });
        CompletableFuture<List<GoodsSpecs>> specsListFuture = YsThread.execute(() -> {
            return iGoodsSpecsService.listByGoodsId(id);
        });
        Goods goods = goodsFuture.join();
        List<GoodsSpecs> specsList = specsListFuture.join();
        goods.setId(null);
        iGoodsService.save(goods);
        ArrayList<GoodsSpecs> saveSpecsList = new ArrayList<>();
        for(GoodsSpecs specs: specsList) {
            if (specs.getIsDelete() == EnableEnum.YES.getEnable()) {
                continue;
            }
            specs.setId(null);
            specs.setGoodsId(goods.getId());
            saveSpecsList.add(specs);
        }
        iGoodsSpecsService.saveBatch(saveSpecsList);
    }

    /**
     * 商品列表查询
     *
     * @param con 查询条件
     * @return 分页数据
     */
    public PageDTO<GoodsVO> pageGoods(GoodsCondition.PageGoodsCon con) {
        // 构建分页对象
        Page<Goods> goodsPage = new Page<>(con.getCurrent(), con.getSize());
        
        // 构建查询条件
        QueryWrapper<Goods> qw = new QueryWrapper<>();
        qw.lambda()
            .select(Goods::getId,
                    Goods::getGoodsName,
                    Goods::getGoodsBanner,
                    Goods::getBrandId,
                    Goods::getOrderNum,
                    Goods::getGoodsPrice,
                    Goods::getStockTotal,
                    Goods::getCreateTime,
                    Goods::getIsLine,
                    Goods::getShowGradeId,
                    Goods::getCategoryId,
                    Goods::getIsCash,
                    Goods::getAdoptCatDaysView,
                    Goods::getGoodsTag,
                    Goods::getGoodsType,
                    Goods::getPetType,
                    Goods::getIsUseTag,
                    Goods::getIsRepeat)
            .eq(Goods::getIsDelete, EnableEnum.NO.getEnable());

        // 分类筛选
        if (ObjectUtils.isNotEmpty(con.getCategoryIdList())) {
            QueryWrapper<MiddleGoodsCategory> middleQw = new QueryWrapper<>();
            middleQw.lambda().in(MiddleGoodsCategory::getCategoryId, con.getCategoryIdList());
            List<Long> goodsIdList = iMiddleGoodsCategoryService.list(middleQw)
                    .stream()
                    .map(MiddleGoodsCategory::getGoodsId)
                    .collect(Collectors.toList());
            if (ObjectUtils.isNotEmpty(goodsIdList)) {
                qw.lambda().in(Goods::getId, goodsIdList);
            } else {
                qw.lambda().in(Goods::getId, -1);
            }
        }

        // 商品名称搜索
        if (StringUtils.isNotEmpty(con.getGoodsName())) {
            qw.lambda().like(Goods::getGoodsName, con.getGoodsName());
        }

        if (ObjectUtils.isNotEmpty(con.getIsLine())) {
            qw.lambda().eq(Goods::getIsLine, con.getIsLine());
        }

        // 品牌筛选
        if (ObjectUtils.isNotEmpty(con.getBrandId())) {
            qw.lambda().eq(Goods::getBrandId, con.getBrandId());
        }

        // 商品类型筛选
        if (ObjectUtils.isNotEmpty(con.getGoodsType())) {
            qw.lambda().eq(Goods::getGoodsType, con.getGoodsType());
        }

        if (ObjectUtils.isNotEmpty(con.getIsCash())) {
            qw.lambda().eq(Goods::getIsCash, con.getIsCash());
        }

        // 排序处理
        if (ObjectUtils.isNotEmpty(con.getIsOrderDesc())) {
            qw.lambda().orderBy(con.getIsOrderDesc() == EnableEnum.YES.getEnable(), 
                false, Goods::getOrderNum);
        }
        if (ObjectUtils.isNotEmpty(con.getIsPriceDesc())) {
            if (con.getIsPriceDesc() == EnableEnum.YES.getEnable()) {
                qw.lambda().orderByDesc(Goods::getGoodsPrice);
            } else {
                qw.lambda().orderByAsc(Goods::getGoodsPrice);
            }
        }
        if (ObjectUtils.isNotEmpty(con.getIsStockDesc())) {
            if (con.getIsStockDesc() == EnableEnum.YES.getEnable()) {
                qw.lambda().orderByDesc(Goods::getStockTotal);
            } else {
                qw.lambda().orderByAsc(Goods::getStockTotal);
            }
        }
        // 默认按ID倒序
        qw.lambda().orderByDesc(Goods::getId);

        // 执行查询
        Page<Goods> page = iGoodsService.page(goodsPage, qw);
        if (page.getRecords().isEmpty()) {
            return new PageDTO<>(1L, 0L, new ArrayList<>());
        }

        // 获取商品ID列表
        List<Long> goodsIds = page.getRecords().stream()
                .map(Goods::getId)
                .collect(Collectors.toList());

        // 获取商品规格信息
        QueryWrapper<GoodsSpecs> specsQw = new QueryWrapper<>();
        specsQw.lambda()
            .in(GoodsSpecs::getGoodsId, goodsIds)
            .eq(GoodsSpecs::getIsDelete, EnableEnum.NO.getEnable());
        Map<Long, List<GoodsSpecs>> specsMap = iGoodsSpecsService.list(specsQw)
                .stream()
                .collect(Collectors.groupingBy(GoodsSpecs::getGoodsId));

        // 获取品牌信息
        Map<Long, String> brandMap = iGoodsBrandService.list()
                .stream()
                .collect(Collectors.toMap(GoodsBrand::getId, GoodsBrand::getBrandName));

        // 获取分类信息
        Map<Long, GoodsCategory> cateMap = iGoodsCategoryService.list()
                .stream()
                .collect(Collectors.toMap(GoodsCategory::getId, Function.identity()));

        // 获取商品分类关联信息
        QueryWrapper<MiddleGoodsCategory> middleQw = new QueryWrapper<>();
        middleQw.lambda().in(MiddleGoodsCategory::getGoodsId, goodsIds);
        Map<Long, List<MiddleGoodsCategory>> goodsCateMap = iMiddleGoodsCategoryService.list(middleQw)
                .stream()
                .collect(Collectors.groupingBy(MiddleGoodsCategory::getGoodsId));

        // 组装返回数据
        List<GoodsVO> resultList = page.getRecords().stream().map(record -> {
            GoodsVO goodsVO = new GoodsVO();
            BeanUtils.copyProperties(record, goodsVO);
            
            // 设置商品类型
            goodsVO.setGoodsMoneyType(record.getIsCash().equals(EnableEnum.YES.getEnable()) ? "现金商品" : "幺币商品");
            
            // 设置分类信息
            List<MiddleGoodsCategory> categories = goodsCateMap.get(record.getId());
            if (ObjectUtils.isNotEmpty(categories)) {
                List<Long> categoryIds = categories.stream()
                        .map(MiddleGoodsCategory::getCategoryId)
                        .collect(Collectors.toList());
                goodsVO.setCategoryIds(categoryIds);
                
                List<String> cateNames = categoryIds.stream()
                        .map(id -> Optional.ofNullable(cateMap.get(id))
                                .map(GoodsCategory::getName)
                                .orElse(null))
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList());
                goodsVO.setCateNames(cateNames);
            }

            // 设置价格
            goodsVO.setGoodsPrice(MoneyUtil.long2Str(record.getGoodsPrice()));
            
            // 设置品牌信息
            goodsVO.setBrandId(record.getBrandId());
            goodsVO.setBrandName(brandMap.get(record.getBrandId()));
            
            // 设置商品属性
            goodsVO.setGoodsType(record.getGoodsType());
            goodsVO.setPetType(JSONArray.parseArray(record.getPetType(), Integer.class));
            goodsVO.setIsUseTag(record.getIsUseTag());
            goodsVO.setIsRepeat(record.getIsRepeat());
            goodsVO.setGoodsBanner(JSONArray.parseArray(record.getGoodsBanner(), String.class));
            goodsVO.setGoodsTag(JSONArray.parseArray(record.getGoodsTag(), String.class));
            
            // 设置规格信息
            List<GoodsSpecs> specs = specsMap.get(record.getId());
            if (ObjectUtils.isNotEmpty(specs)) {
                List<GoodsSpecsVO> specsList = specs.stream().map(spec -> {
                    GoodsSpecsVO specsVO = new GoodsSpecsVO();
                    BeanUtils.copyProperties(spec, specsVO);
                    specsVO.setAttrMap(JSONArray.parseArray(spec.getGoodsSpecs(), SpecsDTO.class));
                    specsVO.setSendGoodsType(spec.getSendGoodsType());
                    return specsVO;
                }).collect(Collectors.toList());
                goodsVO.setSpecsConList(specsList);
            }

            return goodsVO;
        }).collect(Collectors.toList());

        return new PageDTO<>(page.getCurrent(), page.getTotal(), resultList);
    }

}
